package com.nut.spp.interceptor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * jwt加解密工具类
 */
@Component
@Slf4j
public class JwtTokenUtil {

    private static JwtTokenUtil jwtTokenUtil;

    @PostConstruct
    public void init() {
        jwtTokenUtil = this;
    }

    @Value("${jwt.secret}")
    private String tokenSecret;

    @Value("${jwt.clientExpire}")
    private Integer clientExpire;

    @Value("${jwt.merchantExpire}")
    private Integer merchantExpire;

    @Value("${jwt.adminExpire}")
    private Integer adminExpire;

    public static String createClientToken(Object obj) {
        return createToken(obj, jwtTokenUtil.clientExpire, jwtTokenUtil.tokenSecret);
    }

    public static ClientJwt parseClientToken(String token) {
        return parseToken(token, ClientJwt.class, jwtTokenUtil.tokenSecret);
    }

    public static String createMerchantToken(Object obj) {
        return createToken(obj, jwtTokenUtil.merchantExpire, jwtTokenUtil.tokenSecret);
    }

    public static MerchantJwt parseMerchantToken(String token) {
        return parseToken(token, MerchantJwt.class, jwtTokenUtil.tokenSecret);
    }

    public static String createAdminToken(Object obj) {
        return createToken(obj, jwtTokenUtil.adminExpire, jwtTokenUtil.tokenSecret);
    }

    public static AdminJwt parseAdminToken(String token) {
        return parseToken(token, AdminJwt.class, jwtTokenUtil.tokenSecret);
    }

    private static String createToken(Object obj, Integer expire, String secret) {
        Map<String, Object> claims = BeanUtil.beanToMap(obj);
        DateTime expireTime = DateTime.now().offset(DateField.HOUR, expire);

//        Date date = Date.from(LocalDateTime.now().plusHours(7).toInstant(ZoneOffset.of("+8")));

        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(expireTime)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    private static <T> T parseToken(String token, Class<T> clazz, String secret) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            if (!(e instanceof ExpiredJwtException)) {
                log.error("jwt_error," + e);
            }
            claims = null;
        }
        return BeanUtil.toBean(claims, clazz);
    }

}

